package com.amon.amonplayer.watchdog;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.util.Log;
import android.util.Printer;

public class SlowMethodMonitor {
    private static final long TIME_BLOCK = 200;
    private static final Printer PRINTER = new Printer() {
        long startTime = System.currentTimeMillis();

        @Override
        public void println(String x) {
            Log.wtf("TAG", x);
            if (x.startsWith(">>>>>")) {
                startTime = System.currentTimeMillis();
                LogMonitor.getLogMonitor().startMonitor();
            } else if (x.startsWith("<<<<<")) {
                long executeTime = System.currentTimeMillis() - startTime;
                if (executeTime > TIME_BLOCK) {
                    Log.e("TAG", "有耗时函数:" + executeTime);
                }
                LogMonitor.getLogMonitor().removeMonitor();
            }
        }
    };

    public void start() {
        Looper.getMainLooper().setMessageLogging(PRINTER);
    }

    static class LogMonitor implements Runnable {
        private static final LogMonitor LOG_MONITOR = new LogMonitor();
        HandlerThread mHandlerThread;
        Handler mHandler;

        public static LogMonitor getLogMonitor() {
            return LOG_MONITOR;
        }

        private LogMonitor() {
            mHandlerThread = new HandlerThread("log");
            mHandlerThread.start();
            mHandler = new Handler(mHandlerThread.getLooper());
        }

        void startMonitor() {
            mHandler.postDelayed(this, TIME_BLOCK);
        }

        void removeMonitor() {
            mHandler.removeCallbacks(this);
        }

        @Override
        public void run() {
            Log.e("TAG", getStackInfoInfo(Looper.getMainLooper().getThread()));
        }

        private String getStackInfoInfo(Thread thread) {
            StringBuilder stringBuilder = new StringBuilder();
            if (thread != null) {
                StackTraceElement[] stackTraceElements = thread.getStackTrace();
                for (StackTraceElement element : stackTraceElements) {
                    stringBuilder.append(element.toString());
                    stringBuilder.append("\n");
                }
            }
            return stringBuilder.toString();
        }
    }
}
